#ifndef _CFG_H
#define _CFG_H

#include <stdio.h>
#include <stdint.h>
#include <pthread.h>

#include "../public/cJSON.h"
#include "../public/rtlist.h"

typedef enum
{
    CH_FORMAT_16BIT_B0,
    CH_FORMAT_16BIT_B1,
    CH_FORMAT_16BIT_B2,
    CH_FORMAT_16BIT_B3,
    CH_FORMAT_16BIT_B4,
    CH_FORMAT_16BIT_B5,
    CH_FORMAT_16BIT_B6,
    CH_FORMAT_16BIT_B7,
    CH_FORMAT_16BIT_B8,
    CH_FORMAT_16BIT_B9,
    CH_FORMAT_16BIT_B10,
    CH_FORMAT_16BIT_B11,
    CH_FORMAT_16BIT_B12,
    CH_FORMAT_16BIT_B13,
    CH_FORMAT_16BIT_B14,
    CH_FORMAT_16BIT_B15
}ch_format16_1bit_t;

typedef enum
{
    CH_FORMAT_16BIT_B0B1,
    CH_FORMAT_16BIT_B2B3,
    CH_FORMAT_16BIT_B4B5,
    CH_FORMAT_16BIT_B6B7,
    CH_FORMAT_16BIT_B8B9,
    CH_FORMAT_16BIT_B10B11,
    CH_FORMAT_16BIT_B12B13,
    CH_FORMAT_16BIT_B14B15
}ch_format16_2bit_t;

typedef enum
{
    CH_FORMAT_16BIT_B0_B3,
    CH_FORMAT_16BIT_B4_B7,
    CH_FORMAT_16BIT_B8_B11,
    CH_FORMAT_16BIT_B12_B15
}ch_format16_4bit_t;

typedef enum
{
    CH_FORMAT_HIGH,
    CH_FORMAT_LOW
}ch_format_8bit_t;

typedef enum
{
    CH_FORMAT_H1H2,
    CH_FORMAT_H2H1
}ch_format_16bit_t;

typedef enum
{
    CH_FORMAT_H1H2H3H4,
    CH_FORMAT_H4H3H2H1,
    CH_FORMAT_H3H4H1H2,
    CH_FORMAT_H2H1H4H3
}ch_format_32bit_t;

typedef enum
{
    CH_FORMAT_H1_H8,
    CH_FORMAT_H8_H1
}ch_format_64bit_t;

typedef enum
{
    CH_FORMAT_8421,
    CH_FORMAT_5421,
    CH_FORMAT_2421,
    CH_FORMAT_YU3
}ch_format_bcd_t;

typedef enum
{
    CH_FORMAT_32BITB0,
    CH_FORMAT_32BITB1,
    CH_FORMAT_32BITB2,
    CH_FORMAT_32BITB3,
    CH_FORMAT_32BITB4,
    CH_FORMAT_32BITB5,
    CH_FORMAT_32BITB6,
    CH_FORMAT_32BITB7,
    CH_FORMAT_32BITB8,
    CH_FORMAT_32BITB9,
    CH_FORMAT_32BITB10,
    CH_FORMAT_32BITB11,
    CH_FORMAT_32BITB12,
    CH_FORMAT_32BITB13,
    CH_FORMAT_32BITB14,
    CH_FORMAT_32BITB15,
    CH_FORMAT_32BITB16,
    CH_FORMAT_32BITB17,
    CH_FORMAT_32BITB18,
    CH_FORMAT_32BITB19,
    CH_FORMAT_32BITB20,
    CH_FORMAT_32BITB21,
    CH_FORMAT_32BITB22,
    CH_FORMAT_32BITB23,
    CH_FORMAT_32BITB24,
    CH_FORMAT_32BITB25,
    CH_FORMAT_32BITB26,
    CH_FORMAT_32BITB27,
    CH_FORMAT_32BITB28,
    CH_FORMAT_32BITB29,
    CH_FORMAT_32BITB30,
    CH_FORMAT_32BITB31
}ch_format32_1bit_t;

typedef enum
{
    CH_FORMAT_32BIT_B0B1,
    CH_FORMAT_32BIT_B2B3,
    CH_FORMAT_32BIT_B4B5,
    CH_FORMAT_32BIT_B6B7,
    CH_FORMAT_32BIT_B8B9,
    CH_FORMAT_32BIT_B10B11,
    CH_FORMAT_32BIT_B12B13,
    CH_FORMAT_32BIT_B14B15,
    CH_FORMAT_32BIT_B16B17,
    CH_FORMAT_32BIT_B18B19,
    CH_FORMAT_32BIT_B20B21,
    CH_FORMAT_32BIT_B22B23,
    CH_FORMAT_32BIT_B24B25,
    CH_FORMAT_32BIT_B26B27,
    CH_FORMAT_32BIT_B28B29,
    CH_FORMAT_32BIT_B30B31
}ch_format32_2bit_t;

typedef enum
{
    CH_FORMAT_32BIT_B0_B3,
    CH_FORMAT_32BIT_B4_B7,
    CH_FORMAT_32BIT_B8_B11,
    CH_FORMAT_32BIT_B12_B15,
    CH_FORMAT_32BIT_B16_B15,
    CH_FORMAT_32BIT_B20_B23,
    CH_FORMAT_32BIT_B24_B27,
    CH_FORMAT_32BIT_B28_B31
}ch_format32_4bit_t;

// 数据类型定义
typedef enum
{
    CH_TYPE_NULL = 0,
    CH_TYPE_16_1BIT,
    CH_TYPE_16_2BIT,
    CH_TYPE_16_4BIT,
    CH_TYPE_UINT8,
    CH_TYPE_INT8,
    CH_TYPE_UINT16,
    CH_TYPE_INT16,
    CH_TYPE_UINT32,
    CH_TYPE_INT32,
    CH_TYPE_UINT64,
    CH_TYPE_INT64,
    CH_TYPE_FLOAT,
    CH_TYPE_ASCII,
    CH_TYPE_BCD8,
    CH_TYPE_BCD16,
    CH_TYPE_BCD32,
    CH_TYPE_32_1BIT,
    CH_TYPE_32_2BIT,
    CH_TYPE_32_4BIT
} ch_type_t;


// 数据类型定义
typedef enum
{
    CH_ATTRI_YC = 0,
    CH_ATTRI_YX,
    CH_ATTRI_YK,
    CH_ATTRI_YT,
    CH_ATTRI_YM
} ch_attri_t;

typedef struct
{
    char *proj_name; // 工程名称

    char *gw_name;   // 网关名称
    char *location;  // 安装位置
    char *product;   // 网关型号
    char *serial_no; // 网关序列号
    char *zone;      // 时区 "+8:00"

    char *ip;
    char *mask;
    char *gateway;
    uint8_t dhcp;

} cfg_basic_t;

typedef struct cfg_alm_yc_s
{
    // uint8_t alm_en;     // 报警开关
    uint8_t dead_band;  // 死区

    uint8_t LL_en;      // 低低限报警开关
    uint8_t LO_en;      // 低限报警开关
    uint8_t HI_en;      // 高限
    uint8_t HH_en;      // 高高限
    uint8_t DEV_en;     // 偏差
    uint8_t RATE_en;    // 变化率

    uint32_t LL_val;    // 阈值
    uint32_t LO_val;
    uint32_t HI_val;
    uint32_t HH_val;
    uint32_t DEV_val;   
    uint32_t RATE_val;  

    uint32_t DEV_set;   // 设定值
    uint16_t RATE_cyc;  // 周期	（秒）

    uint16_t alm_delay; // 0-65535 延时时间（毫秒）
} cfg_alm_yc_t;

typedef struct cfg_alm_yx_s
{
    // uint8_t alm_pr;
    uint8_t normal_val; // 0; 1; 2(固定不变)
    // uint8_t alm_en;     // 报警开关
    // uint16_t alm_delay; // 0-65535 延时时间（毫秒）
} cfg_alm_yx_t;

typedef struct cfg_alm_s
{
    uint8_t alm_type; //0-遥测类告警；1-遥信类告警
    void *content;
} cfg_alm_t;

typedef struct cfg_node_s
{
    uint16_t id;
    uint16_t group;

    uint16_t reg_add; 
    uint8_t reg_type; // 寄存器数据类型
    uint8_t endian;   // 字节序

    uint8_t dcm;      // 小数位
    uint8_t k;        // 小数品质
    uint8_t fun_num;  // 功能码
    uint8_t style;    // 类型

    char *data_name;
    char *unit;
    char *calc;       // 计算表达式

    struct cfg_node_s *next;
} cfg_node_t;


typedef struct cfg_temp_s
{
    char *name;
    uint16_t cnt;
    cfg_node_t *node_list;

    struct cfg_temp_s *next;
} cfg_temp_t;

typedef struct cfg_ch_s
{
    // uint16_t id; // 测点id
    float data; // 计算值

    // cfg_alm_t *alm;
    cfg_node_t *node;

    // struct cfg_ch_s *next;
} cfg_ch_t;

typedef struct cfg_subdev_s
{
    uint16_t group_id;
    cfg_ch_t *ch; // 测点
    uint16_t valcntsum; // 测点数
    struct cfg_subdev_s *next;
} cfg_subdev_t;

typedef struct cfg_su_s
{
    uint8_t sn[14]; // 序列号

    uint16_t addr;      // 地址
    uint16_t id;        // ID
    uint16_t loop;      // 回路号
    uint16_t valcntsum; // 测点数

    uint8_t state; // 状态,1--在线,0--掉线
    void *param;

    char *name;      // 设备名称
    char *temp_name; // 设备模板
    cfg_temp_t *template;
    cfg_ch_t *ch; // 测点

    cfg_subdev_t *subdev_list;

    struct cfg_su_s *next;
} cfg_su_t;

typedef struct
{
    char *freq;
} cfg_lora_t;

typedef struct
{
    char *baudrate; // 波特率
    char *format;   // 奇偶校验位
} cfg_serial_t;

typedef struct
{
    char *ip;  // 本地IP地址
    char *port; // 本地端口号
} cfg_enet_t;

typedef struct
{
    char *apn;      // APN
    char *username; // 用户名
    char *password; // 密码
} cfg_4g_t;

typedef struct
{
    char *type;    // 端口类型,COM1-16,TCP-Server,TCP-Client,MQTT,4G,VIRUTAL
    void *setting; // 参数设置项,class_serial_t和class_enet_t
    
    // void* ctx;     // 端口句柄

    // int (*fopen) (void* pu);
    // int (*fclose) (void* pu);
    // int (*freconnect) (void* pu);
    // int (*fread) (void* pu,uint8_t *msg, int len,int timeout);
    // int (*fwrite) (void* pu,uint8_t *msg, int len);
    // int (*fflush) (void* pu);
} cfg_port_t;

typedef struct
{
    uint16_t gapTime;
    uint16_t waitTimer;
    uint8_t reSend;
    uint8_t saveMsg;
    // ...

    char *IP;
    char *Port;
    uint8_t maxReg;

} cfg_proto_coll_t;

typedef struct
{
    void *cjson;            // 每个节点的json跟，后续需要安装具体协议进行解析
    pthread_mutex_t lock;   // 每个节点的互斥锁
    void *param;            // 节点下其他的参数
    void *dlmodule;         // 存放动态库的接口，目前仅有init/run/msg这三个接口
    void *api;              // 每个节点的方法，包括msg,fresh...
    struct rb_root *rbroot; // 红黑树根节点
} cfg_handler_t;

typedef struct cfg_pu_s
{
    uint8_t type;       // 0--采集通道 ; 0--转发通道
    uint8_t enable;     // 0--不使能 ; 1--使能
    uint8_t devsumlist; // 当前通道 挂载的设备
    uint8_t id;         // 当前通道 ID  rs485_1-8 (0-7)  eth1-11
    char *name;         // 名称

    uint32_t pkg_send; // 当前通道发送包数
    uint32_t pkg_recv; // 当前通道接收包数

    cfg_su_t *su;
    cfg_port_t port;
    char *protoname;    // 协议名称
    cfg_proto_coll_t *proto_coll;

    cfg_handler_t hanlder; // 节点句柄

    struct cfg_pu_s *next;
} cfg_pu_t;

extern cJSON *cfg_create_root(const char *json_buf);
extern cfg_basic_t *cfg_create_basic(cJSON *root);
extern cfg_pu_t *cfg_create_coll_node(cJSON *root_sys, cJSON *root_clt);
extern cfg_pu_t *cfg_create_trans_node(cJSON *root_sys,cJSON *root_clt);

#endif